package cn.com.zetatech.maple.core.utils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author cheng.cao@zetatech.com.cn
 */
public class BeanUtils {

    private static final Map<String, Object> beanCache = new ConcurrentHashMap<>();
    private static final ReadWriteLock rwlock = new ReentrantReadWriteLock();

    /**
     * 单例独享
     *
     * @param className
     * @param <T>
     * @return
     */
    public static <T> T getBean(String className) {
        rwlock.readLock().lock();
        Object value = beanCache.get(className);
        try {
            if (value == null) {
                rwlock.readLock().unlock();
                rwlock.writeLock().lock();
                try {
                    if (null == (value = beanCache.get(className))) {
                        try {
                            Class c = Class.forName(className);
                            Object o = c.newInstance();
                            beanCache.put(className, o);
                            value = o;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                } finally {
                    rwlock.writeLock().unlock();
                    rwlock.readLock().lock();
                }
            }
        } finally {
            rwlock.readLock().unlock();
        }
        return (T) value;
    }

}
